<script setup lang="ts" generic="T extends Record<string, any>">
import { Download, Filter } from '@element-plus/icons-vue'
import { useSimpleExportLists } from './useSimpleExportLists'
import type { TableColumn, TableScopedColumn } from '@/types'
import type { TableInstance } from 'element-plus'

defineOptions({
  inheritAttrs: false,
})
const props = withDefaults(
  defineProps<{
    loading: boolean
    lists: T[]
    columns: TableColumn<T>[]
    height?: string | number
    operateWidth?: string | number
    showToolbox?: boolean
    popoverWidth?: string | number
    operateAlign?: string
    noBorderBottom?: boolean
    customDownload?: boolean
    hideDownload?: boolean
    emptyAttrs?: object
  }>(),
  {
    loading: true,
    operateWidth: '100px',
    height: '100%',
    popoverWidth: 'auto',
    operateAlign: 'center',
    emptyAttrs() {
      return {}
    },
  },
)
const emits = defineEmits<{
  (e: 'download', v: any[]): void
}>()
// 显示声明插槽类型
defineSlots<{
  operate: (props: {
    row: T
    column: TableScopedColumn
    index: number
  }) => void
  actions: () => void
}>()
const attrs = useAttrs()
const checkedKeys = ref(
  props.columns.filter(v => !v.hidden).map(v => v.key),
)
const checkedColumns = computed<any[]>(() => {
  return props.columns.filter(v =>
    checkedKeys.value.includes(v.key),
  )
})
const tableRef = ref<TableInstance>()

const route = useRoute()
function clickDownload() {
  if (props.customDownload) {
    emits('download', unref(checkedColumns))
    return
  }
  const { exportXlsx } = useSimpleExportLists<T>({
    columns: checkedColumns.value,
    lists: props.lists,
  })

  exportXlsx(route.meta.title)
}

watch(() => props.columns, () => {
  checkedKeys.value = props.columns.filter(v => !v.hidden).map(v => v.key)
}, { deep: true })

function tableOnMethod(method: string, ...args: any[]) {
  if (method && tableRef.value) {
    return tableRef.value[method as keyof TableInstance]?.(...args)
  }
}

defineExpose({
  tableOnMethod,
})
</script>

<template>
  <div class="width-fill lists-head flex">
    <div v-if="$slots.actions" class="flex-fillRemaining lists-actions">
      <slot name="actions" />
    </div>
    <div v-if="showToolbox" class="margin-left-auto flex-incompressible lists-toolbox self-end">
      <ElPopover :teleported="false" :width="popoverWidth">
        <template #reference>
          <ElButton type="primary" :icon="Filter" circle />
        </template>
        <div class="max-h-lg overflow-auto">
          <ElCheckboxGroup v-model="checkedKeys">
            <ElCheckbox
              v-for="column in columns" :key="column.key" :value="column.key"
              :disabled="column.type !== undefined" style="display: flex"
            >
              {{ column.label }}
            </ElCheckbox>
          </ElCheckboxGroup>
        </div>
      </ElPopover>
      <ElTooltip v-if="!hideDownload" content="导出" placement="top">
        <ElButton class="margin-left-xs" type="success" :icon="Download" circle @click="clickDownload" />
      </ElTooltip>
    </div>
  </div>
  <div class="alpha-block flex-1 overflow-auto dark:p-[10px]">
    <ElTable
      ref="tableRef"
      v-loading="loading" element-loading-custom-class="global-loading" class="table-lists-table"
      :class="{ 'no-border-bottom': noBorderBottom }" border
      :height="height" :data="lists" style="user-select: text;"
      :tooltip-options="{
        popperClass: 'max-w-300px',
      }"
      v-bind="attrs"
    >
      <template #empty>
        <TableEmpty v-bind="emptyAttrs" />
      </template>
      <template
        v-for="{
          key,
          type,
          render,
          ...column
        } in checkedColumns" :key="key"
      >
        <ElTableColumn v-if="type" :type="type" v-bind="column" />
        <ElTableColumn v-else-if="render" v-bind="column">
          <template #default="scoped">
            <RenderComponent :render="render" :row="scoped.row" :column="scoped.column" :index="scoped.$index" />
            <!-- <component :is="render(row)" :row="row" :column="col"></component> -->
          </template>
        </ElTableColumn>
        <ElTableColumn v-else v-bind="column" />
      </template>
      <ElTableColumn
        v-if="$slots.operate" label="操作" prop="operate" :align="operateAlign" :width="operateWidth"
        :fixed="$slots.operate ? 'right' : undefined"
      >
        <template #default="scoped">
          <slot name="operate" :row="scoped.row" :column="scoped.column" :index="scoped.$index" />
        </template>
      </ElTableColumn>
    </ElTable>
  </div>
</template>

<style scoped>
.lists-actions {
  &> :not(form) {
    margin-bottom: 18px;
  }
}

.lists-toolbox {
  margin-bottom: 18px;
}

.table.no-border-bottom :deep(.el-table__inner-wrapper::before) {
  display: none;
}
</style>
